package com.hongye.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jdom.JDOMException;

import com.alibaba.druid.util.StringUtils;
import com.hongye.app.model.OrderInfoModel;
import com.hongye.app.model.PaymentModel;
import com.hongye.util.HttpUtils;
import com.hongye.util.Utils;
import com.hongye.util.WeixinUtils;
import com.jfinal.aop.Clear;
import com.jfinal.core.Controller;

/**
 * 微信相关
 * @author Administrator
 *
 */
public class WeixinController extends Controller{
	
	private static Logger log = Logger.getLogger(WeixinController.class);
	
	public WeixinController() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * APP调用统一下单，完成预付单
	 * @author lifuqiang
	 * 2017-2-15
	 * @throws IOException 
	 * @throws JDOMException 
	 */
	@Clear
	public void unifiedorder(){
		String orderids = this.getPara("orderids");//订单id集合
		String spbill_create_ip = this.getPara("spbill_create_ip");//用户端实际ip
		List<OrderInfoModel> orders = OrderInfoModel.getOrderByINOrderids(orderids);
		boolean boo = orderids.contains(",");
		Map<String, Object> sParaTemp = new HashMap<String, Object>();
		if(boo){
			float summoney = (float) 0.0;
			for (OrderInfoModel item : orders) {
				summoney += item.getFloat("total_price");
			}
			OrderInfoModel orderinfo = new OrderInfoModel();//生成新的订单 批量支付的总订单
			orderinfo.set("type", 1).set("orderids", orderids).set("total_price", summoney).set("payment_channel", "1").set("order_status", 0).set("order_sn", Utils.getOrderSN()).save();
			sParaTemp.put("body", "热播购平台付款");//商品描述
			sParaTemp.put("out_trade_no", orderinfo.get("order_sn"));//商户订单号
			sParaTemp.put("total_fee", (int)(summoney * 100));//总金额
		}else{
			sParaTemp.put("body", "热播购平台付款");//商品描述
			sParaTemp.put("out_trade_no", orders.get(0).get("order_sn"));//商户订单号
			sParaTemp.put("total_fee", (int) (orders.get(0).getFloat("total_price") * 100));//总金额
		}
		sParaTemp.put("appid", WeixinUtils.appid);//应用ID
		sParaTemp.put("mch_id", WeixinUtils.mch_id);//商户号
		sParaTemp.put("nonce_str", WeixinUtils.getRandomString(32));//随机字符串
		sParaTemp.put("sign_type", WeixinUtils.sign_type);//签名类型
		sParaTemp.put("spbill_create_ip", spbill_create_ip);//终端IP
		sParaTemp.put("notify_url", WeixinUtils.notify_url);//微信支付异步通知回调地址
		sParaTemp.put("trade_type", WeixinUtils.trade_type);//交易类型
		sParaTemp.put("sign", WeixinUtils.formatQueryParaMap(sParaTemp));//签名
		if(log.isInfoEnabled()){log.info("weixin unifiedorder map="+sParaTemp);}
		String resultxml = HttpUtils.sendPostXml(WeixinUtils.unifiedorder_url, WeixinUtils.getRequestXml(sParaTemp));
 		Map<String, Object> result = WeixinUtils.doXMLParse(resultxml);
		if(log.isInfoEnabled()){log.info("weixin result="+result);}
		Map<String, Object> rs = new HashMap<String, Object>();
		rs.put("status", "fal");
		rs.put("ordersn", sParaTemp.get("out_trade_no"));
		if(null != result && result.get("return_code").equals("SUCCESS") && result.get("result_code").equals("SUCCESS")){
			Map<String, Object> apprs = new HashMap<String, Object>();
			apprs.put("appid", WeixinUtils.appid);//应用ID
			apprs.put("partnerid", WeixinUtils.mch_id);//商户号
			apprs.put("prepayid", result.get("prepay_id"));//预支付交易会话ID
			apprs.put("package", "Sign=WXPay");//扩展字段
			apprs.put("noncestr", WeixinUtils.getRandomString(32));//随机字符串
			apprs.put("timestamp", Utils.currentTimeMillis());//时间戳
			apprs.put("sign", WeixinUtils.formatQueryParaMap(apprs));//签名
			rs.put("apprs", apprs);
			rs.put("status", "suc");
			PaymentModel.dao.addPayment(orders, "weixin");
		}
		this.renderJson(rs);

	}
	
	/**
	 * 微信支付 异步回调接口
	 * @author liushaomin
	 * 2017年2月23日
	 */
	@Clear
	public void notify_url(){
		try {
			BufferedReader reader =  this.getRequest().getReader();
			String line = "";
	        StringBuffer strxml = new StringBuffer();
	        PrintWriter writer = this.getResponse().getWriter();
	        while ((line = reader.readLine()) != null) {
	        	strxml.append(line);
            }
	        if(reader != null){  
                reader.close();  
            }  
	        if(!StringUtils.isEmpty(strxml.toString())){
	        	 Map<String,Object> para  = WeixinUtils.doXMLParse(strxml.toString());
	        	 if(log.isInfoEnabled()){log.info("weixin notify_url result="+para);}
	        	if("SUCCESS".equals(para.get("return_code"))){
	        		String sign = WeixinUtils.formatQueryParaMap(para);
	        		 if(sign.equals(para.get("sign"))){//修改订单状态
	        			 String ordersn = para.get("out_trade_no").toString();//订单号
	        			 OrderInfoModel order = OrderInfoModel.getOrderBySN(ordersn);
	        			 if(order.getInt("order_status") == 2){//订单状态已经修改
	        				 writer.write(WeixinUtils.backWeixin("SUCCESS", "OK"));
	        				 if(log.isInfoEnabled()){log.info("weixin notify_url  SUCCESS OK");}
	        			 }else if(order.getInt("order_status") == 0){
	        				 if(order.getInt("type") == 1){//多个订单业务逻辑
	        					 String orderids = order.getStr("orderids");
	        					 order.set("order_status", 2).update();
	        					 WeixinUtils.UpOrder(orderids, para);
	        				 }else{//单个订单业务逻辑
	        					 WeixinUtils.UpOrder_single(ordersn, para);
	        				 }
	        				 writer.write(WeixinUtils.backWeixin("SUCCESS", "OK"));
	        				 if(log.isInfoEnabled()){log.info("weixin notify_url  SUCCESS OK");}
	        			 }else{
	        				 writer.write(WeixinUtils.backWeixin("FAIL", "本地服务器失败"));
    						 if(log.isInfoEnabled()){log.info("weixin notify_url  FAIL 本地服务器失败");}
	        			 }
	        		 }else{
	        			 writer.write(WeixinUtils.backWeixin("FAIL", "验证签名失败"));
	        			 if(log.isInfoEnabled()){log.info("weixin notify_url  FAIL 验证签名失败");}
	        		 }
	        	}else{
	        		writer.write(WeixinUtils.backWeixin("FAIL", "微信返回fail"));
	        		if(log.isInfoEnabled()){log.info("weixin notify_url  FAIL 微信返回fail");}
	        	}
//	        	if(writer!=null){  
//                    writer.close();  
//                }  
	        }else{
	        	writer.write(WeixinUtils.backWeixin("FAIL", "微信返回结果为空"));
	        	if(log.isInfoEnabled()){log.info("weixin notify_url  FAIL 微信返回结果为空");}
	        }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 查询支付状态接口
	 * @author liushaomin
	 * 2017年2月20日
	 * msg_code 移动端参数 0 成功 -1错误（调用支付错误）-2用户取消  其他错误代码记录日志
	 * 微信返回的交易状态  trade_state SUCCESS—支付成功，REFUND—转入退款，NOTPAY—未支付，CLOSED—已关闭，REVOKED—已撤销（刷卡支付），USERPAYING--用户支付中，PAYERROR--支付失败(其他原因，如银行返回失败)
	 * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_2&index=4
	 */
	@Clear
	public void orderquery(){
		System.err.println("weixin================= orderquery");
		String ordersn = this.getPara("ordersn");
		String msg_code = this.getPara("msg_code");
		OrderInfoModel order = OrderInfoModel.getOrderBySN(ordersn);
		Map<String, Object> rs = new HashMap<String, Object>();
		rs.put("money", order.getFloat("total_price"));
		rs.put("status", "fal");
		if(msg_code.equals("0")){//成功
			if(order.getInt("order_status") == 2){//返回支付成功
				rs.put("status", "suc");
			}else{//查询微信支付结果，修改本地订单状态
				Map<String, Object> para = WeixinUtils.query(order.getStr("trade_num"));
				String sign = WeixinUtils.formatQueryParaMap(para);
				if(para.get("return_code").equals("SUCCESS") && para.get("result_code").equals("SUCCESS")){
					if(sign.equals(para.get("sign"))){//验证签名
						if(para.get("trade_state").equals("SUCCESS")){
							 if(order.getInt("type").equals("1")){//多个订单业务逻辑
								 order.set("order_status", "2").update();
								 String orderids = order.getStr("orderids");
								 WeixinUtils.UpOrder(orderids, para);
							 }else{//单个订单业务逻辑
								 WeixinUtils.UpOrder_single(ordersn, para);
							 }
							 rs.put("status", "suc");
						}
					}
				}//其他情况暂不处理
			}
		}else{//修改payment状态为 取消
			System.err.println("order-----------------type----------------" + order.getInt("type"));
			if(order.getInt("type") == 1){//多个订单
				String orderids = order.getStr("orderids");
				List<PaymentModel> payments = PaymentModel.getListByOrderids_Channel(orderids, "weixin");
				for (PaymentModel item : payments) {
					item.set("state", 1).update();
				}
			}else{//单个订单
				PaymentModel payment = PaymentModel.getPaymentByOrderSN_Channel_state(ordersn, "weixin", 0);
				payment.set("state", 1).update();
			}
		}
		this.renderJson(rs);
	}
}
